import cv2
import os
import re
import shutil
from PIL import Image


def extract_frames_from_videos(video_folder, output_folder, frame_interval=1, video_extensions=(".mp4", ".avi", ".mov", ".mkv")):
    """
    从指定文件夹中的所有视频提取帧，并保存为 JPG 图片。

    参数:
    - video_folder: 包含视频文件的文件夹路径
    - output_folder: 存放提取帧的根目录
    - frame_interval: 处理间隔
    """
    os.makedirs(output_folder, exist_ok=True)

    video_files = [f for f in os.listdir(video_folder) if f.lower().endswith(video_extensions)]

    for video_file in video_files:
        video_path = os.path.join(video_folder, video_file)
        video_name = os.path.splitext(video_file)[0]

        video_output_folder = os.path.join(output_folder, video_name)
        os.makedirs(video_output_folder, exist_ok=True)

        cap = cv2.VideoCapture(video_path)
        frame_count = 0
        saved_frame_count = 0

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            if frame_count % frame_interval == 0:
                frame_filename = os.path.join(video_output_folder, f"{video_name}_{frame_count}.jpg")
                cv2.imwrite(frame_filename, frame)
                saved_frame_count += 1

            frame_count += 1

        cap.release()
        print(f"视频 {video_file} 处理完成，共 {frame_count} 帧，保存 {saved_frame_count} 帧到 {video_output_folder}")

    print("所有视频处理完成！")


def get_beside_nums_files(folder_path, files):
    """
    返回一个文件夹下纯数字命名的图片最大编号和其他非数字命名的文件列表
    Args:
        folder_path: 该文件夹的位置
        files: 该文件夹下所有的图片
    :return:
            max_number: 该文件夹下数字命名图片的最大数字
            non_number_file:不是数字命名的图片
    """
    number_pattern = re.compile(r'^(\d+)\.[a-zA-Z]{1,5}$')  # 纯数字加后缀的，比如 5.jpg

    existing_numbers = []
    non_number_files = []

    # 第一次遍历，区分已有数字命名和非数字命名
    for filename in files:
        file_path = os.path.join(folder_path, filename)
        if os.path.isfile(file_path):
            match = number_pattern.match(filename)
            if match:
                existing_numbers.append(int(match.group(1)))
            else:
                non_number_files.append(filename)

    # 找到已有最大数字
    max_number = max(existing_numbers) if existing_numbers else 0
    return max_number, non_number_files


def rename_images_in_folder(folder_path, start_count, use_num):
    """
    将文件夹下非纯数字命名的图片文件，从当前最大数字后续编号重新命名。

    Args:
        folder_path: 图片所在的文件夹路径。
        start_count: 命名的起始下标
        use_num: 是否不更改纯数字图片的命名  True：不更改
    """

    files = sorted(os.listdir(folder_path))
    if use_num:
        max_number, non_number_files = get_beside_nums_files(folder_path, files)
    else:
        max_number = 0
        non_number_files = files
    # 对非数字文件做临时改名（避免重名冲突）
    temp_suffix = "_temp_rename"
    for idx, filename in enumerate(non_number_files):
        old_path = os.path.join(folder_path, filename)
        extension = os.path.splitext(filename)[1]
        temp_name = f"temp_{idx}{temp_suffix}{extension}"
        temp_path = os.path.join(folder_path, temp_name)
        os.rename(old_path, temp_path)

    # 重新获取所有临时文件，按顺序重命名
    temp_files = sorted([f for f in os.listdir(folder_path) if temp_suffix in f])

    for i, filename in enumerate(temp_files, start=max_number + 1):
        old_path = os.path.join(folder_path, filename)
        extension = os.path.splitext(filename)[1]
        new_filename = f"{i+start_count}{extension}"
        new_path = os.path.join(folder_path, new_filename)
        os.rename(old_path, new_path)

    print("重命名完成！")


def convert_to_png(folder_path):
    """
    将指定文件夹下所有图片文件转换为真正的PNG格式

    参数:
        folder_path : 目标文件夹路径
    """
    supported_formats = ['.jpg', '.jpeg', '.bmp', '.tiff', '.webp']

    for filename in os.listdir(folder_path):
        file_path = os.path.join(folder_path, filename)
        if not os.path.isfile(file_path):
            continue

        name_without_ext, ext = os.path.splitext(filename)
        ext_lower = ext.lower()

        if ext_lower not in supported_formats:
            continue

        try:
            with Image.open(file_path) as img:
                if img.mode == 'RGBA':
                    img = img.convert('RGB')
                new_filename = f"{name_without_ext}.png"
                new_file_path = os.path.join(folder_path, new_filename)
                img.save(new_file_path, 'PNG', optimize=True)
                print(f"已转换: {filename} -> {new_filename}")

                os.remove(file_path)

        except Exception as e:
            print(f"转换失败 {filename}: {str(e)}")


def rename_all_to_png(folder_path):
    """
    将指定文件夹下所有文件的后缀名修改为 .png

    参数:
        folder_path : 目标文件夹路径
    """
    for filename in os.listdir(folder_path):
        file_path = os.path.join(folder_path, filename)

        if not os.path.isfile(file_path):
            continue
        name_without_ext, _ = os.path.splitext(filename)

        new_filename = name_without_ext + '.png'
        new_file_path = os.path.join(folder_path, new_filename)
        os.rename(file_path, new_file_path)
        print(f"已重命名: {filename} -> {new_filename}")


def copy_matching_extension_files(img_folder, sour_folder, dst_folder, extension):
    """
    将与图片文件同名前缀的extension文件从txt_folder中复制到dst_folder中
    参数:
        img_folder: 图片文件所在文件夹路径
        sour_folder: 原始 extension 文件所在文件夹路径
        dst_folder: 复制 extension 文件的目标文件夹路径
    """
    if not os.path.exists(dst_folder):
        os.makedirs(dst_folder)

    for img_file in os.listdir(img_folder):
        img_name, _ = os.path.splitext(img_file)
        extension_name = img_name + f".{extension}"
        extension_path = os.path.join(sour_folder, extension_name)
        if os.path.isfile(extension_path):
            dst_path = os.path.join(dst_folder, extension_name)
            shutil.copy(extension_path, dst_path)
            print(f"已复制: {extension_name}")
        else:
            print(f"未找到匹配的{extension}: {extension_name}")


def add_prefix_to_files(folder_path, prefix):
    """
    给指定文件夹下所有文件添加前缀
    参数:
        folder_path (str): 文件夹路径
        prefix (str): 要添加的前缀
    """
    for filename in os.listdir(folder_path):
        old_path = os.path.join(folder_path, filename)

        if not os.path.isfile(old_path):
            continue
        new_filename = prefix + filename
        new_path = os.path.join(folder_path, new_filename)
        if os.path.exists(new_path):
            print(f"文件已存在，跳过重命名: {new_filename}")
            continue
        os.rename(old_path, new_path)
        print(f"重命名: {filename} -> {new_filename}")


if __name__ == "__main__":

    # # 函数一: 根据视频提取图像
    # video_folder = r"./dataset/video_air_launch"  # 视频文件夹
    # output_folder = r"./dataset/Image_air_launch"  # 输出图片文件夹
    # frame_interval = 5  # 多少帧存一张
    # video_extensions = (".mp4", ".avi", ".mov", ".mkv")  # 视频的后缀
    # extract_frames_from_videos(video_folder, output_folder, frame_interval, video_extensions)
    #
    # # 函数二： 将文件夹下的图片重新命名   稍微修改一下就是原来是数字的就不命名
    # folder = r"F:\yolo_summary\yolo_code\car\521\no_damaged"  # 图片文件夹
    # start_count = 1934   # 图片开始的数字
    # use_num = False   # 是否处理纯数字命名图片
    # rename_images_in_folder(folder, start_count=start_count, use_num=use_num)
    #
    # 函数三 将文件夹下的图片文件更改后缀为png
    folder_path = r"F:\project\523_ship\images_png"   # 文件夹路径
    rename_all_to_png(folder_path)
    # convert_to_png(folder_path)

    # 函数四 将图片对应的后缀文件找出来
    # source_img_dir = r'F:\project\good_ship\show_result'
    # source_dir = r'F:\project\good_ship\AllImages'
    # target_dir = r'F:\project\good_ship\AllImages_need'
    # extension = 'bmp'  # 想要找的对应的后缀
    # copy_matching_extension_files(source_img_dir, source_dir, target_dir, extension)

    # 函数五 将文件夹下的图片添加前缀
    # add_prefix_to_files(r"F:\project\project_code_tools\dataset_2025_4\ship_label", "oldship_")

